from pydantic import BaseModel
from fastapi import APIRouter, Request, Depends
import user_agents
from utils import db_pool, token_required, password_hasher, key_manager, token_manager

router = APIRouter()
admin = "admin"


class UserCreateModel(BaseModel):
    username: str


class UserLoginModel(BaseModel):
    username: str
    password: str


class UserUpdateModel(BaseModel):
    username: str
    username_new: str


@router.get('/PublicKeyQuery')
def query_user():
    return {"key": key_manager.get_public_key()}


def get_user_agent_parser(request: Request):
    """依赖项：解析User-Agent"""
    user_agent = request.headers.get("user-agent", "")
    return user_agents.parse(user_agent)


@router.post('/Login')
def user_login(data: UserLoginModel, req: Request,
               ua_parser: user_agents.parsers.UserAgent = Depends(get_user_agent_parser)):
    user_info = {
        "username": data.username.strip(),
        "ip": req.client.host,
        "浏览器": f"{ua_parser.browser.family} {ua_parser.browser.version_string}",
        "操作系统": f"{ua_parser.os.family} {ua_parser.os.version_string}",
        "设备品牌": ua_parser.device.family,
        "设备类型": "手机" if ua_parser.is_mobile else "平板" if ua_parser.is_tablet else "电脑" if ua_parser.is_pc else "机器人/爬虫程序"
    }
    if data.username.strip() == "":
        return {"status": False, "error_message": "username为空"}
    sql = "select password from user where username=%s;"
    res = db_pool.query(sql, (data.username.strip(),))
    if len(res) == 0:
        return {"status": False, "error_message": "用户名 或密码错误"}
    try:
        password = key_manager.decrypt(data.password)
    except Exception as err:
        print(err)
        return {"status": False, "error_message": "公钥过期"}
    if not password_hasher.verify_password(password, res[0]["password"]):
        return {"status": False, "error_message": "用户名或 密码错误"}
    return {"status": True, "token": token_manager.get_token(user_info)}


@router.post('/UserCreate')
@token_required
def create_user(data: UserCreateModel, req: Request):
    token = req.headers.get('token', None)
    opr_username = token_manager.token_pool.get(token, {}).get("username", "")
    if opr_username != admin:
        return {"status": False, "error_message": "操作失败"}
    if data.username.strip() == "":
        return {"status": False, "error_message": "username为空"}
    # 创建用户时哈希密码
    hashed_password = password_hasher.hash_password("123456")
    sql = "insert user(username, password) values(%s, %s);"
    execute_result = db_pool.execute_sql(sql, (data.username.strip(), hashed_password))
    print("执行结果:", execute_result)
    if execute_result["status"] != "success":
        return {"status": False}
    return {"status": True}


@router.post('/UserQuery')
@token_required
def query_user(data: UserCreateModel, req: Request):
    token = req.headers.get('token', None)
    opr_username = token_manager.token_pool.get(token, {}).get("username", "")
    if opr_username != admin:
        return {"status": False, "error_message": "操作失败"}
    res = db_pool.query("select id, username from user where username<>%s;", (admin,))
    return {"data": res}


@router.post('/CurrentLoginQuery')
@token_required
def query_current_login_user(data: UserCreateModel, req: Request):
    token = req.headers.get('token', None)
    opr_username = token_manager.token_pool.get(token, {}).get("username", "")
    if opr_username != admin:
        return {"status": False, "error_message": "操作失败"}
    res = []
    for i in token_manager.token_pool:
        item = {k: v for k, v in token_manager.token_pool[i].items()}
        item["id"] = i
        item.pop("expiry")
        res.append(item)
    return {"status": True, "data": res}


@router.post('/ForceLogout')
@token_required
def force_user_logout(data: UserCreateModel, req: Request):
    token = req.headers.get('token', None)
    opr_username = token_manager.token_pool.get(token, {}).get("username", "")
    if opr_username != admin:
        return {"status": False, "error_message": "操作失败"}
    token = data.username
    token_manager.token_pool.pop(token)
    return {"status": True}


@router.post('/PersonalQuery')
@token_required
def query_personal(data: UserCreateModel, req: Request):
    token = req.headers.get('token', None)
    opr_username = token_manager.token_pool.get(token, {}).get("username", "")
    sql = "select id, username from user where username=%s;"
    res = db_pool.query(sql, (opr_username,))
    return {"data": res}


@router.post('/UserDelete')
@token_required
def delete_user(data: UserCreateModel, req: Request):
    token = req.headers.get('token', None)
    opr_username = token_manager.token_pool.get(token, {}).get("username", "")
    if opr_username != admin:
        return {"status": False, "error_message": "操作失败"}
    sql = "delete from user where username=%s and username<>%s;"
    execute_result = db_pool.execute_sql(sql, (data.username.strip(), admin))
    print("执行结果:", execute_result)
    if execute_result["status"] != "success":
        return {"status": False}
    return {"status": True}


@router.post('/UserUpdate')
@token_required
def update_user(data: UserCreateModel, req: Request):
    token = req.headers.get('token', None)
    opr_username = token_manager.token_pool.get(token, {}).get("username", "")
    if opr_username != admin:
        return {"status": False, "error_message": "操作失败"}
    if data.username.strip() == "":
        return {"status": False, "error_message": "username为空"}
    if data.username_new.strip() == "":
        return {"status": False, "error_message": "username_new为空"}
    sql = "update user set username=%s where username=%s and username<>%s;"
    execute_result = db_pool.execute_sql(sql, (data.username_new.strip(), data.username.strip(), admin))
    print("执行结果:", execute_result)
    if execute_result["status"] != "success":
        return {"status": False}
    return {"status": True}


@router.post('/PasswordReset')
@token_required
def reset_password(data: UserCreateModel, req: Request):
    token = req.headers.get('token', None)
    opr_username = token_manager.token_pool.get(token, {}).get("username", "")
    if opr_username != admin:
        return {"status": False, "error_message": "操作失败"}
    if data.username.strip() == "":
        return {"status": False, "error_message": "username为空"}
    # 创建用户时哈希密码
    hashed_password = password_hasher.hash_password("123456")
    sql = "update user set password=%s where username=%s and username<>%s;"
    execute_result = db_pool.execute_sql(sql, (hashed_password, data.username.strip(), admin))
    print("执行结果:", execute_result)
    if execute_result["status"] != "success":
        return {"status": False}
    return {"status": True}


@router.post('/PasswordUpdate')
@token_required
def update_password(data: UserLoginModel, req: Request):
    token = req.headers.get('token', None)
    opr_username = token_manager.token_pool.get(token, {}).get("username", "")
    try:
        password = key_manager.decrypt(data.password)
    except Exception as err:
        print(err)
        return {"status": False, "error_message": "公钥过期"}
    hashed_password = password_hasher.hash_password(password)
    sql = "update user set password=%s where username=%s;"
    execute_result = db_pool.execute_sql(sql, (hashed_password, opr_username))
    print("执行结果:", execute_result)
    if execute_result["status"] != "success":
        return {"status": False}
    return {"status": True}


@router.post('/UserRename')
@token_required
def rename_user(data: UserCreateModel, req: Request):
    token = req.headers.get('token', None)
    opr_username = token_manager.token_pool.get(token, {}).get("username", "")
    if data.username.strip() == "":
        return {"status": False, "error_message": "username为空"}
    sql = "update user set username=%s where username=%s;"
    execute_result = db_pool.execute_sql(sql, (data.username.strip(), opr_username))
    print("执行结果:", execute_result)
    if execute_result["status"] != "success":
        return {"status": False}
    token_manager.token_pool[token]["username"] = data.username.strip()
    return {"status": True}


@router.post('/Logout')
@token_required
def user_logout(data: UserCreateModel, req: Request):
    token = req.headers.get('token', None)
    token_manager.token_pool.pop(token)
    return {"status": True}
